#define NUM_OF_EXAMPLES 15
#define NUM_OF_FEATURES 117684
#define SUBWINDOW_SIZE 14 * 35
#define T 1

#include <iostream>

using namespace std;

void classifier_selection(double err[], double threshold[], double parity[]);
void print1D(const double a[], int dim);
void prep_features(double f[][NUM_OF_EXAMPLES]) {
	for (int i = 0; i < NUM_OF_FEATURES; i++)
		for (int j = 0; j < NUM_OF_EXAMPLES; j++)
			f[i][j] = (double)rand() / RAND_MAX;
}

void prep_labels(int l[], const double f[][NUM_OF_EXAMPLES]) {
	for (int i = 0; i < NUM_OF_EXAMPLES; i++)
		l[i] = f[0][i] >= 0.5 ? 1 : 0;
}

void get_pos_neg(int &pos, int &neg, const int l[]) {
	for (int i = 0; i < NUM_OF_EXAMPLES; i++)
		l[i] == 1 ? pos++ : neg++;
}

void prep_weights(double w[], const int l[], const int pos, const int neg) {
	for (int i = 0; i < NUM_OF_EXAMPLES; i++)
		w[i] = l[i] == 1 ?  1.0 / (2 * pos) : 1.0 / (2 * neg);
}

void normalize_weights(double w[]) {
	double w_sum = 0;

	for (int i = 0; i < NUM_OF_EXAMPLES; i++)
		w_sum += w[i];
	
	for (int i = 0; i < NUM_OF_EXAMPLES; i++)
		w[i] /= w_sum;
}

void read_feature(double cf[], const double f[], const int f_size) {
	memcpy(cf, f, f_size);
}

void weak_classifier(double &ce, double &ct, double &cp, 
					 const double mu_neg,
					 const double sig_neg,
					 const double mu_pos,
					 const double sig_pos,
					 const double cf[]) {

}

void sort(double *data, int *index , int length) {
    int temp_i;
    double temp_d;
        
    for(int i = 0 ; i < length - 1; i++) {
        for(int j = i + 1; j < length; j++) {
            if (data[i] > data[j]) {
                temp_d = data[i];
                data[i] = data[j];
                data[j] = temp_d;
				
                temp_i = index[i];
                index[i] = index[j];
                index[j] = temp_i;
		    }
        }
    }
}

int main(int argc, char** argv) {
	
	double features[NUM_OF_FEATURES][NUM_OF_EXAMPLES], weights[NUM_OF_EXAMPLES];
	int labels[NUM_OF_EXAMPLES], pos_num = 0, neg_num = 0;
	int feature_size = sizeof(double) * NUM_OF_EXAMPLES;
	
	/* Supposingly 2 outputs */
	int h_indices[T];
	double beta[T];

	prep_features(features);
	prep_labels(labels, features);
	get_pos_neg(pos_num, neg_num, labels);
	prep_weights(weights, labels, pos_num, neg_num);

	for (int t = 0; t < T; t++) {
		normalize_weights(weights);
		
		double  err[NUM_OF_FEATURES], threshold[NUM_OF_FEATURES], parity[NUM_OF_FEATURES];
		
		classifier_selection(err, threshold, parity);		
		
		int err_indices[NUM_OF_FEATURES];
		for (int i = 0; i < NUM_OF_FEATURES; i++)
			err_indices[i] = i;
		for (int i = 0; i < NUM_OF_EXAMPLES; i++)
			sort(err, err_indices, NUM_OF_FEATURES);
		
		/* Choose the classifier */
		h_indices[t] = err_indices[0];
		
		/* Update the weights */
		beta[t] = err[0] / (1 - err[0]);
		
		
	}

	return 0;
}

void classifier_selection(double err[], double threshold[], double parity[]) {
	FILE *fid_feat = fopen("f_out.bin", "rb");
	FILE *fid_gvec = fopen("g_out.bin", "rb");

	for (int i = 0; i < NUM_OF_FEATURES; i++) {
			double	cur_feat[NUM_OF_EXAMPLES], cur_gvec[SUBWINDOW_SIZE], cur_err, cur_threshold, cur_parity;
			
			fread(cur_feat, sizeof(int), NUM_OF_EXAMPLES, fid_feat);
			fread(cur_gvec, sizeof(int), SUBWINDOW_SIZE, fid_gvec);

			//read_feature(cur_feat, features[i], feature_size);
			//weak_classifier(cur_err, cur_threshold, cur_parity, mu_negative, sig_negative, mu_positive, sig_positive, cur_feat);

			err[i] = cur_err;
			threshold[i] = cur_threshold;
			parity[i] = cur_parity;
	}

	fclose(fid_feat);
	fclose(fid_gvec);
}

void print1D(const double a[], int dim) {

	for (int i = 0; i < dim; i++)
		printf("%.2f ", a[i]);

	printf("\n");
}